﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;
using Spring.Data;
using Spring.Data.Common;
using Spring.Data.Core;

namespace Vision.Utilities.Common
{
    public static class FileSystemUtility
    {
        public static string Combine(params string[] paths)
        {
            return Path.Combine(paths).Replace('/', '\\');
        }

        public static void CopyFolder(string sourceFolderPath, string targetFolderPath, bool overwrite = true)
        {
            if (string.IsNullOrEmpty(sourceFolderPath) || string.IsNullOrEmpty(targetFolderPath))
                return;

            if (!Directory.Exists(sourceFolderPath))
                return;

            if (!Directory.Exists(targetFolderPath))
                Directory.CreateDirectory(targetFolderPath);

            foreach (var entry in Directory.GetFileSystemEntries(sourceFolderPath))
            {
                var targetEntry = Combine(targetFolderPath, Path.GetFileName(entry));
                if (Directory.Exists(entry))
                {
                    CopyFolder(entry, targetEntry, overwrite);
                }
                else
                {
                    File.Copy(entry, targetEntry, overwrite);
                }
            }
        }

        public static void DeleteFolder(string folderPath, bool recursive, params string[] excludedFileEntryNames)
        {
            if (string.IsNullOrEmpty(folderPath) || !Directory.Exists(folderPath))
                return;

            excludedFileEntryNames = excludedFileEntryNames.Where(c => !string.IsNullOrEmpty(c)).ToArray();

            if (!excludedFileEntryNames.Any())
            {
                Directory.Delete(folderPath, recursive);
            }
            else
            {
                ClearSubFolders(folderPath, recursive, excludedFileEntryNames);

                if (!Directory.GetFileSystemEntries(folderPath).Any() && !excludedFileEntryNames.Any(c => c.Equals(folderPath, StringComparison.InvariantCultureIgnoreCase)))
                    Directory.Delete(folderPath);
            }
        }

        public static void ClearSubFolders(string folderPath, bool recursive, params string[] excludedFileEntryNames)
        {
            if (string.IsNullOrEmpty(folderPath) || !Directory.Exists(folderPath))
                return;

            foreach (var entry in Directory.GetFileSystemEntries(folderPath))
            {
                if (excludedFileEntryNames.Any(c => entry.Equals(c, StringComparison.InvariantCultureIgnoreCase)))
                    excludedFileEntryNames = excludedFileEntryNames.Where(c => !entry.Equals(c, StringComparison.InvariantCultureIgnoreCase)).ToArray();
                else
                {
                    // File
                    if (!Directory.Exists(entry))
                    {
                        File.Delete(entry);
                    }
                    // Folder
                    else
                    {
                        DeleteFolder(entry, recursive, excludedFileEntryNames);
                    }
                }
            }
        }
    }
}